import { Text, View, ScrollView, Image } from '@tarojs/components'
import React, { useCallback, useState, memo, useEffect, useMemo } from 'react'
import Taro from '@tarojs/taro'
import { useDispatch } from 'react-redux'
import dayjs from 'dayjs'
import timezone from 'dayjs/plugin/timezone'
import Images from '@ASSET/Images'
import PlanProgress from '@COMPONENTS/PlanManagement/PlanProgress'
import PlanCardItem from '@COMPONENTS/PlanManagement/PlanCardItem'
import { CustomI18NITF } from '@INTERFACES/Common'
import { DailyContentITF, DailyContentsITF, PlanSummaryITF } from '@INTERFACES/PlanManagement'
import managementPlanActions from '@ACTIONS/managementPlan'
import { Analytic_Type } from '@CONSTANTS/analytic'
import { getPlatform, formatUnitTime } from '@UTILS/common'
import ExpandText from '@COMPONENTS/ExpandText'
import style from './PlanManagementSchedule.module.scss'

const { isWeb } = getPlatform()
dayjs.extend(timezone)
dayjs.tz.setDefault('Asia/Shanghai')
const DAY_TO_WEEK = ['日', '一', '二', '三', '四', '五', '六']
const MIN_LENGTH = 7

interface ScheduleProps {
  data: DailyContentsITF[]
  title: string
  currentDay: number
  pId: string
  createdDate: number
  planSummary: PlanSummaryITF
  hasMainBanner?: boolean
  virtualHeight?: number
}

const PlanManagementSchedule: React.FC<ScheduleProps> = ({
  data, title, currentDay = 1, pId, createdDate, planSummary, hasMainBanner, virtualHeight = 0
}) => {
  const dispatch = useDispatch()
  const { dispatchSetDailyContentViewed } = managementPlanActions
  const setDailyContentViewed = useCallback(payload => dispatch(dispatchSetDailyContentViewed(payload)), [dispatch, dispatchSetDailyContentViewed])
  const [day, setDay] = useState(currentDay)
  const [taskDesc, setTaskDesc] = useState('')
  const { Contents: contents, DailyTitle } = data[day - 1] || {}
  const onHandler = useCallback(id => {
    setDailyContentViewed({ PainManagementId: pId, EntityId: id, CurrentDay: day })
  }, [setDailyContentViewed, pId, day])
  useEffect(() => {
    setDay(currentDay)
    const todayContent = data[currentDay - 1]?.Contents || []
    const completeNum = todayContent?.filter(({ Viewed }) => Viewed).length
    setTaskDesc(`（${completeNum}/${todayContent.length}）`)
  }, [currentDay, data])
  const currentDate = useMemo(
    () => dayjs(createdDate).add(day - 1, 'day').format('YYYY-MM-DD')
    , [createdDate, day]
  )

  return (
    <View className={style.container}>
      <PlanProgress title={title} data={planSummary} hasMainBanner={hasMainBanner} virtualHeight={virtualHeight} />
      <RenderDateMemo
        data={data}
        currentDay={currentDay}
        day={day}
        setDay={setDay}
        createdDate={createdDate}
        taskDesc={taskDesc}
      />
      <RenderTitle data={DailyTitle} isShow={currentDay === day} />
      <RenderContent data={contents} onHandler={onHandler} day={day} currentDay={currentDay} planId={pId} currentDate={currentDate} />
    </View>
  )
}

interface RenderDateProps {
  data: DailyContentsITF[]
  currentDay: number
  day: number
  setDay: (idx: number) => void
  createdDate: number
  taskDesc: string
}

const RenderDate: React.FC<RenderDateProps> = ({
  data, currentDay, day, setDay, createdDate, taskDesc,
}) => {
  const [visible, setVisible] = useState<boolean>(false)
  const [selectedDay, setSelectedDay] = useState<number>(0)
  const firstDate = dayjs(createdDate)
  const firstWeekDay = firstDate.day()
  const len = data.length >= MIN_LENGTH ? data.length : MIN_LENGTH
  const max_click_num = currentDay + 3
  const tempArr = new Array(len).fill(0)
  const { days, weeks } = tempArr.reduce((preObj, currentValue, currentIndex) => {
    const currentDate = firstDate.add(currentIndex, 'day')
    const newObj = { ...preObj }
    newObj.days.push(currentDate.date())
    newObj.weeks.push(DAY_TO_WEEK[(firstWeekDay + currentIndex) % 7])
    return newObj
  }, { days: [], weeks: [] })
  const finishedArr = tempArr.map((i, idx) => {
    if ((currentDay - 1) < idx || !data[idx]) return false
    return !(data[idx].Contents?.filter(({ Viewed }) => !Viewed).length > 0)
  })
  const isToday = currentDay === day
  const currentMonth = firstDate.add(day - 1, 'day').month()
  const title = isToday ? '今日任务进度' : `${currentMonth + 1}月${days[day - 1]}日`

  const onClick = () => {
    Taro.tracker.trackEvent(Analytic_Type.num_plan_calendar.eventId)
    setVisible(!visible)
  }

  useEffect(() => {
    if (!isWeb) {
      setSelectedDay(day)
      return
    }
    if (visible) {
      setTimeout(() => setSelectedDay(day), 1)
    } else {
      setSelectedDay(0)
    }
  }, [day, visible])

  const onResetToday = (e: { stopPropagation: () => void }) => {
    e.stopPropagation?.()
    setDay(currentDay)
  }

  return (
    <View className={style.whiteBg}>
      <View className={style.scheduleRow} onClick={onClick}>
        <View className={style.rowCenter}>
          <View className={style.block} />
          <Text className={style.scheduleTitle}>
            {title}
            {isToday && <Text className={style.todayDesc}>{taskDesc}</Text>}
          </Text>
        </View>
        <View className={style.rowCenter}>
          {!isToday && (
            <View className={style.resetToday} onClick={onResetToday}>
              <Text className={style.resetText}>今</Text>
            </View>
          )}
          <Image src={Images.managePlan.schedule} className={style.scheduleIcon} />
        </View>
      </View>
      {visible && (
        <ScrollView
          scrollX
          scrollWithAnimation
          enhanced
          showScrollbar={false}
          className={style.scheduleDate}
          scrollIntoView={`day_${Math.max(selectedDay - 3, 1)}`}
          id="renderDate"
        >
          {
            weeks.map((i: string, idx: number) => (
              <RenderScheduleMemo
                key={`${i}_${idx}`}
                day={day}
                idx={idx}
                weekText={i}
                dayNum={days[idx]}
                setDay={setDay}
                endNum={max_click_num}
                currentDay={currentDay}
                finished={finishedArr[idx]}
              />
            ))
          }
        </ScrollView>
      )}
    </View>
  )
}

interface RenderScheduleProps {
  day: number
  idx: number
  setDay: (idx: number) => void
  weekText: string
  dayNum: number
  endNum: number
  currentDay: number
  finished: boolean
}

const RenderSchedule: React.FC<RenderScheduleProps> = ({
  day, idx, setDay, weekText, dayNum, endNum, currentDay, finished
}) => {
  const isToday = currentDay === (idx + 1)
  const isActive = day === (idx + 1)
  const canClick = idx < endNum
  const firstDay = currentDay === 1
  const onPress = () => canClick && setDay(idx + 1)
  return (
    <View key={`${weekText}_${dayNum}_${idx}`} id={`day_${idx + 1}`} className={style.inlineBlock}>
      <View className={`${style.dateBlock} ${firstDay ? style.width53 : ''} ${(firstDay && isToday) ? style.firstDay : ''}`} onClick={onPress}>
        <Text className={canClick ? style.weekTitle : style.threeDaysText}>
          {weekText}
        </Text>
        <View className={`${style.box} ${isToday ? style.todayBox : ''} ${isActive ? style.activeBox : ''}`}>
          <Text className={canClick ? style[isActive ? 'activeTitle' : 'dayTitle'] : style.disableDayTitle}>
            {formatUnitTime(dayNum)}
          </Text>
        </View>
        {(finished && !isActive) && <View className={style.doneBlock} />}
      </View>
    </View>
  )
}

interface TitleProps {
  data?: CustomI18NITF
  isShow?: boolean
}

const RenderTitle: React.FC<TitleProps> = ({
  data, isShow
}) => {
  const title = data?.zh || ''
  const onClickExpand = useCallback(expand => {
    expand && Taro.tracker.trackEvent(Analytic_Type.num_plan_expand_text.eventId)
  }, [])
  const hidden = !isShow || !title
  return (
    <View className={`${style.descBox} ${hidden ? style.fixWebapp : ''}`}>
      <View className={style.descView}>
        <Image src={Images.decision.icon_decision_entry} className={style.titleIcon} />
        <ExpandText
          expandText="展开全部"
          numberOfLines={3}
          lineHeight={20}
          text={title}
          expandTextBgClass={style.expandTextBg}
          expandTextClass={style.expandText}
          onClickExpand={onClickExpand}
          textClass={style.desc}
          hiddenBtnIcon
        />
      </View>
    </View>
  )
}

interface RenderContentProps {
  data: DailyContentITF[]
  onHandler: (id: string) => void
  planId: string
  day: number
  currentDay: number
  currentDate: string
}

const RenderContent: React.FC<RenderContentProps> = ({
  data, onHandler, planId, day, currentDay, currentDate
}) => {
  const hasArrayData = Array.isArray(data) && data?.length > 0
  if (!hasArrayData) return null
  const d = data.find(({ Viewed }) => !Viewed)
  const { EntityId = '', EntityType = '' } = d || {}
  return (
    <View className={style.planContent}>
      {
        data.map((item, idx) => (
          <PlanCardItem
            planId={planId}
            day={day}
            currentDay={currentDay}
            currentDate={currentDate}
            key={`${item.EntityId}-${idx}`}
            data={item}
            onHandler={onHandler}
            isFirst={EntityId === item.EntityId || (!EntityId && EntityType === item.EntityType)}
          />
        ))
      }
    </View>
  )
}

const RenderDateMemo = memo(RenderDate)
const RenderScheduleMemo = memo(RenderSchedule)

export default PlanManagementSchedule
